(function () {
    "use strict";

    angular.module('core').factory('toolsService', factory);
    factory.$inject = ['toastr'];

    function factory(toastr) {

        var _instance = {
            buildChart: function (elementId, yTitle, series, print) {
                ///elementId: id do elemento a ser populado
                ///yTitle: Título do eixo vertical
                ///series: Array de objetos com as configurações e dados da serie
                ///print: opcional - indica se é para impressão ou não

                ///return: bool retorna verdadeiro se as séries estiverem todas vazias.

                var datalabels = false;
                if (print)
                    datalabels = true;

                var xDateType = false;
                var isEmpty = true;

                /*Por questão de compatibilidade e parsing do angularjs as datas devem ser enviadas via string no formato "Date.UTC(yyyy,MM,dd)".
                estas string serão convertidas em datas logo abaixo.*/
                for (var i = 0; i < series.length; i++) {
                    if (series[i].data.length > 0) {
                        isEmpty = false;
                        if (series[i].data[0][0].toString().indexOf("Date.UTC") >= 0) {
                            xDateType = true;
                            for (var n = 0; n < series[i].data.length; n++)
                                series[i].data[n][0] = eval(series[i].data[n][0]);
                        }
                    }
                }

                $(elementId).highcharts(
                    {
                        'chart': {
                            renderTo: elementId,
                            backgroundColor: 'transparent',
                            zoomType: 'x',
                        },
                        'credits': { enabled: false },
                        'title': { text: '' },
                        'subtitle': { text: '' },
                        'exporting': { enabled: false },
                        'plotOptions': {
                            area: { dataLabels: { enabled: datalabels } },
                            arearange: { dataLabels: { enabled: datalabels } },
                            //areaspline: { dataLabels: { enabled: datalabels }, marker: { enabled: false } },
                            areaspline: { dataLabels: { enabled: datalabels } },
                            areasplinerange: { dataLabels: { enabled: datalabels } },
                            bar: { dataLabels: { enabled: datalabels } },
                            box: { dataLabels: { enabled: datalabels } },
                            bubble: { dataLabels: { enabled: datalabels } },
                            column: { dataLabels: { enabled: datalabels } },
                            columnrange: { dataLabels: { enabled: datalabels } },
                            errorbar: { dataLabels: { enabled: datalabels } },
                            funnel: { dataLabels: { enabled: datalabels } },
                            gauge: { dataLabels: { enabled: datalabels } },
                            heatmap: { dataLabels: { enabled: datalabels } },
                            //line: { dataLabels: { enabled: datalabels }, marker: { enabled: false } },
                            line: { dataLabels: { enabled: datalabels } },
                            pie: { dataLabels: { enabled: datalabels }, showInLegend: true },
                            polygon: { dataLabels: { enabled: datalabels } },
                            pyramid: { dataLabels: { enabled: datalabels } },
                            scatter: { dataLabels: { enabled: datalabels } },
                            series: { dataLabels: { enabled: datalabels } },
                            solidgauge: { dataLabels: { enabled: datalabels } },
                            //spline: { dataLabels: { enabled: datalabels }, marker: { enabled: false } },
                            spline: { dataLabels: { enabled: datalabels } },
                            treemap: { dataLabels: { enabled: datalabels } },
                            waterfall: { dataLabels: { enabled: datalabels } }
                        },
                        'series': series,
                        'tooltip': {
                            shared: false,
                            xDateFormat: '%d/%m/%Y',
                            pointFormat: '<span style="color:{series.color}">{series.name}</span>:<b>{point.y}</b><br/>'
                        },
                        'xAxis': {
                            'type': xDateType ? 'datetime' : 'linear',
                            'categories': xDateType ? null : [],
                            'dateTimeLabelFormats': { day: '%d/%m/%y', month: '%b/%Y', year: '%Y' },
                            'gridLineColor': '#fafafa',
                            'gridLineWidth': 1,
                        },
                        'yAxis': {
                            'title': { text: yTitle },
                            'gridLineColor': '#f0f0f0',
                            'gridLineWidth': 1,
                        },
                        'legend': {
                            'align': 'center',
                            'layout': 'horizontal',
                            'verticalAlign': 'bottom',
                            enabled: true,
                        },
                    });

                for (var i = 0; i < series.length; i++)
                    if (series[i].hidden)
                        $(elementId).highcharts().series[i].hide();

                return isEmpty;
            },
            date: {
                toString: function (val) {
                    var yyyy = val.getFullYear().toString();
                    var mm = (val.getMonth() + 1).toString(); // getMonth() is zero-based
                    var dd = val.getDate().toString();
                    return (dd[1] ? dd : "0" + dd[0]) + '/' + (mm[1] ? mm : "0" + mm[0]) + '/' + yyyy; // padding
                },
                toStringFull: function (val) {
                    var yyyy = val.getFullYear().toString();
                    var MM = (val.getMonth() + 1).toString(); // getMonth() is zero-based
                    var dd = val.getDate().toString();
                    var hh = val.getHours().toString();
                    var mm = val.getMinutes().toString();
                    return (dd[1] ? dd : "0" + dd[0]) + '/' + (MM[1] ? MM : "0" + MM[0]) + '/' + yyyy + ' ' + (hh[1] ? hh : "0" + hh[0]) + ':' + (mm[1] ? mm : "0" + mm[0]); // padding
                },
                hoje: (new Date(new Date().setHours(0, 0, 0, 0))),
                getPrimeiroDiaMes: function (data) {
                    if (!data)
                        data = new Date(new Date().setHours(0, 0, 0, 0));
                    else {
                        /* cria nova instância para não alterar o parâmetro por referência */
                        data = new Date(data);
                    }
                    data.setDate(1);

                    return data;
                },
                getUltimoDiaMes: function (data) {
                    if (!data)
                        data = new Date(new Date().setHours(0, 0, 0, 0));
                    else {
                        /* cria nova instância para não alterar o parâmetro por referência */
                        data = new Date(data);
                    }

                    data.setDate(1);
                    data.setMonth(data.getMonth() + 1);
                    data.setDate(data.getDate() - 1);

                    return data;
                },
                getMesPassado: function () {
                    const data = new Date(new Date().setHours(0, 0, 0, 0));
                    data.setMonth(data.getMonth() - 1);
                    return data;
                },
                getNMesesAtras: function (nMeses, data) {
                    if (!nMeses)
                        nMeses = 1;
                    if (!data)
                        data = new Date(new Date().setHours(0, 0, 0, 0));
                    else {
                        /* cria nova instância para não alterar o parâmetro por referência */
                        data = new Date(data);
                    }
                    data.setMonth(data.getMonth() - nMeses);
                    return data;
                },
                getNMeses: function (nMeses, data) {
                    if (!nMeses)
                        nMeses = 1;
                    if (!data)
                        data = new Date(new Date().setHours(0, 0, 0, 0));
                    else {
                        /* cria nova instância para não alterar o parâmetro por referência */
                        data = new Date(data);
                    }
                    data.setMonth(data.getMonth() + nMeses);
                    return data;
                },
                getAnoPassado: function () {
                    const data = new Date(new Date().setHours(0, 0, 0, 0));
                    data.setFullYear(data.getFullYear() - 1);
                    return data;
                },
                getNAnosAtras: function (nAnos, data) {
                    if (!nAnos)
                        nAnos = 1;
                    if (!data)
                        data = new Date(new Date().setHours(0, 0, 0, 0));
                    else {
                        /* cria nova instância para não alterar o parâmetro por referência */
                        data = new Date(data);
                    }

                    data.setFullYear(data.getFullYear() - nAnos);

                    return data;
                },
                getNAnos: function (nAnos, data) {
                    if (!nAnos)
                        nAnos = 1;
                    if (!data)
                        data = new Date(new Date().setHours(0, 0, 0, 0));
                    else {
                        /* cria nova instância para não alterar o parâmetro por referência */
                        data = new Date(data);
                    }

                    data.setFullYear(data.getFullYear() + nAnos);

                    return data;
                },
                getPeriodoMes: function (mes) {
                    const data = new Date(new Date().getFullYear(), mes, 1);
                    const periodo = {
                        de: data,
                        ate: new Date(date.setMonth() + 1) - 1
                    };
                    return periodo;
                }
            },
            toastr: toastr,
            getStars: function (count) {
                var list = [];
                for (var i = 0; i < count; i++)
                    list.push("star");
                for (var i = count; i < 5; i++)
                    list.push("star_border");
                return list;
            },
            goTop: function () {
                $('html,body').stop().animate({ scrollTop: 0 }, 300);
            },
            goTo: function (elementId) {
                $('html,body').animate({ scrollTop: $(elementId).position().top - 60 }, 500);
            },
            getScrollPosition: function () {
                return $('html,body').scrollTop();
            },
            setScrollPosition: function (position) {
                $('html,body').scrollTop(position);
            },
            getHoje: function () {
                return (new Date(new Date().setHours(0, 0, 0, 0)));
            },
            flattenObject: function (ob) {
                var toReturn = {};
                var flatObject;
                for (var i in ob) {
                    if (!ob.hasOwnProperty(i)) {
                        continue;
                    }
                    if ((typeof ob[i]) === 'object') {
                        flatObject = _instance.flattenObject(ob[i]);
                        for (var x in flatObject) {
                            if (!flatObject.hasOwnProperty(x)) {
                                continue;
                            }
                            toReturn[i + (!!isNaN(x) ? '.' + x : '')] = flatObject[x];
                        }
                    } else {
                        toReturn[i] = ob[i];
                    }
                }
                return toReturn;
            },
            flattenArray: function (_array) {
                var data = [];
                for (var i = 0; i < _array.length; i++) {
                    data.push(_instance.flattenObject(_array[i]));
                }
                return data;
            },
            toggleColunasDinamicas: function () {
                $('#pivot-table table>tbody:first-child>tr:first-child>td:first-child').toggle();
                $('#pivot-table .pvtAxisContainer').toggle();
                $('#pivot-table .pvtVals').toggle();
                $('#report-paper').toggleClass('report-paper-operacional');

            },
            closeColunasDinamicas: function () {
                $('#pivot-table table>tbody:first-child>tr:first-child>td:first-child').hide();
                $('#pivot-table .pvtAxisContainer').hide();
                $('#pivot-table .pvtVals').hide();
            },
            maps: {
                /* recebe o objeto de endereço e retorna a url de google maps para embutir em iframe */
                getEmbeddedUrl: (item) => {
                    if (!item)
                        return null;

                    return 'https://maps.google.com/maps?q=' + item.Linha1 + ';' + item.Linha2 + ';' + item.Linha3 + ';' + item.Bairro + ';' + item.Cidade.Nome + ';' + item.Estado.Sigla + ';' + item.Cep + '&output=embed'
                }
            },
        };

        return _instance;
    }

})();


